import nci60.data.maxquant.Experiment
import nci60.data.maxquant.ExperimentClass
import nci60.data.maxquant.Project
import nci60.data.maxquant.RawFile

def uploadService = ctx.getBean("uploadService")

def config = new ConfigSlurper().parse(new File('scripts/4_upload_experiment.conf').toURL())


def project
if(config.experiment.containsKey('id')){
    println 'get experiment by id..'
    project = Project.findById(config.experiment.id)
}else{
    println 'generating experiment..'
    project = new Project(name:config.experiment.name)
    if (!project.save(flush:true)) {
        project.errors.each {println it}
    }
}
println 'id: '+project.id+' name: '+project.name+'\n'

//RawFile.executeUpdate('delete from RawFile r where r.currentProject=:proj',[proj:project])
//Experiment.executeUpdate('delete from Experiment e where e.currentProject=:proj',[proj:project])
//ExperimentClass.executeUpdate('delete from ExperimentClass e where e.currentProject=:proj',[proj:project])


println 'generating celllines and cell line classes..'
def celllineName = config.celllines.columns.celllineName
def pNumberName = config.celllines.columns.pNumber

def cls = [:]
def celllineIndex = 0
def pNumberIndex = 0

config.cellLineClasses.each{shortName,longName->
    def c = ExperimentClass.findByCurrentProjectAndName(project, longName)
    if(c==null){
        c = new ExperimentClass(currentProject:project, name:longName)
        if (!c.save(flush:true)) {
            c.errors.each {println it}
        }
    }
    cls.put(shortName, c)
}


def file = new File(config.celllines.file)
println '-reading file: ' + file.absolutePath

def celllines = [:]
file.eachWithIndex(){line,index->
    def splittedLine = line.split('\t')
    if(index==0){
        celllineIndex = splittedLine.findIndexOf{it==celllineName}
        pNumberIndex = splittedLine.findIndexOf{it==pNumberName}
    }else{
        def pNumber = splittedLine[pNumberIndex]
        def name = splittedLine[celllineIndex]
        def celllineClass = name.split('_')[0]
        def cl = Experiment.findByCurrentProjectAndPNumber(project, pNumber)
        if(cl==null){
            cl = new Experiment(currentProject:project, name:name, currentClass:cls[celllineClass], pNumber:pNumber)
            if (!cl.save(flush:true)) {
                cl.errors.each {println it}
            }
        }
        celllines.put(pNumber, cl)
    }
}

config.celllines.exclude.each(){pNumber
    def cl = celllines[pNumber]
    cl.excluded = true
    if (!cl.save(flush:true)) {
        cl.errors.each {println it}
    }
}

println 'cell line classes generated!\n'
println 'generating raw file classes..'

def rawFiles = []
config.rawFiles.folders.each(){rf->
    def dir = new File(rf)
    dir.eachFile {fi->
        if (fi.isFile()) {
            rawFiles.add(fi)
        }
    }
}
config.rawFiles.files.each(){rf->
    rawFiles.add(new File(rf))
}

rawFiles.each(){rawFile->
    def rawFileName = rawFile.getName().replaceAll('.RAW','')
    def pNumber = rawFileName.split('_')[2]
    def rf = RawFile.findByCurrentProjectAndName(project, rawFileName)
    if(rf==null){
        rf = new RawFile(currentProject:project, name:rawFileName, experiment:celllines[pNumber])
    }
    if (!rf.save(flush:true)) {
        rf.errors.each {println it}
    }
}
println 'raw files classes generated!\n'

println 'processing protein groups file..'
def tempFolder = config.outputFolder
def separator = File.separator

new File(''+ tempFolder + separator + 'upload_order.txt').withWriter { out ->
    out.writeLine('ProteinGroup.sql')
    out.writeLine('ProteinGroupExperiment.sql')
    out.writeLine('IdentifiedProteins.sql')
    out.writeLine('LeadingProteins.sql')
    out.writeLine('peptides.sql')
    out.writeLine('peptide_experiments.sql')
    out.writeLine('peptide_charge.sql')
    out.writeLine('peptide_in_protein.sql')
    out.writeLine('MsMs.sql')
    out.writeLine('aplSpectra.sql')
}

def proteinGroupFile = new File(config.proteinGroups.file)

def proteinGroupProperties = config.proteinGroups.columns.general
def proteinGroupExperimentProperties = config.proteinGroups.columns.experiments

def proteinIdInFile = config.proteinGroups.columns.linking.proteinIds
def groupIdInFile = proteinGroupProperties.idInFile
def contaminantInFile = proteinGroupProperties.contaminant
def reverseInFile = proteinGroupProperties.reverse

uploadService.uploadProteinGroupTable(proteinGroupFile, tempFolder, proteinGroupProperties,  project)
uploadService.uploadProteinGroupExperimentTable(proteinGroupFile, tempFolder, proteinGroupExperimentProperties, groupIdInFile, project)
uploadService.identifyProteins(proteinGroupFile, tempFolder, proteinIdInFile, groupIdInFile, contaminantInFile, reverseInFile, project)
println 'processing protein groups file done!\n'

println 'processing peptides file..'
def peptideFile = new File(config.peptides.file)
def peptideProperties = config.peptides.columns.general
def peptideExperimentProperties = config.peptides.columns.experiments
def leadingRazorProteinName = config.peptides.columns.linking.leadingRazorProtein
def peptideIdInFile = peptideProperties.idInFile
def chargeName = config.peptides.columns.linking.charge
def proteinsName = config.peptides.columns.linking.proteinsMainIds
def sequenceName = peptideProperties.sequence
def contaminantName = peptideProperties.contaminant
def reverseName = peptideProperties.reverse

uploadService.uploadPeptideTable(peptideFile, tempFolder, peptideProperties, leadingRazorProteinName, project)
uploadService.uploadPeptideExperimentTable(peptideFile, tempFolder, peptideExperimentProperties, peptideIdInFile, project)
uploadService.uploadPeptideChargeTable(peptideFile, tempFolder, peptideIdInFile, chargeName, project)
uploadService.uploadPeptideInProteinTable(peptideFile, tempFolder, peptideIdInFile, proteinsName, sequenceName, contaminantName, reverseName, project)

def peptideIsRazorInFile = config.proteinGroups.columns.linking.peptideIsRazor
def peptideIdsInFileName = config.peptides.columns.linking.peptideIds

uploadService.updatePeptideIsRazor(proteinGroupFile, proteinIdInFile, contaminantInFile, reverseInFile, peptideIdsInFileName, peptideIsRazorInFile, project)
println 'processing peptides file done!\n'

println 'processing msms file..'
def msmsFile = new File(config.msms.file)
def msmsProperties = config.msms.columns

uploadService.uploadMsMs(msmsFile, tempFolder, msmsProperties, project)
println 'processing msms file done!\n'

println 'processing apl spectra files..'
uploadService.uploadAPLSpectra(rawFiles, tempFolder, project)
println 'processing apl spectra files done!\n'